package com.example.fuckble;

import android.app.Application;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.util.Log;

import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.callback.BleWriteCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.scan.BleScanRuleConfig;
import com.clj.fastble.utils.HexUtil;

import java.util.List;

import static android.bluetooth.BluetoothGattCharacteristic.PROPERTY_INDICATE;
import static android.bluetooth.BluetoothGattCharacteristic.PROPERTY_NOTIFY;
import static android.bluetooth.BluetoothGattCharacteristic.PROPERTY_READ;
import static android.bluetooth.BluetoothGattCharacteristic.PROPERTY_WRITE;
import static android.bluetooth.BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE;

public class Fast {
    public static final String LOCK = "AA210003";
    public static final String MAC = "9C:A5:25:D0:05:99";
    public static final String UUID_S3 = "0003cdd0-0000-1000-8000-00805f9b0131";
    public static final String UUID_S3_C1 = "0003cdd1-0000-1000-8000-00805f9b0131"; // 不可读 不可写
    public static final String UUID_S3_C2 = "0003cdd2-0000-1000-8000-00805f9b0131"; // 不可读 可写
    private final BleManager bleManager = BleManager.getInstance();
    public void start(Application application) {
        bleManager.init(application);
        bleManager.enableLog(true).setReConnectCount(1, 5000).setOperateTimeout(5000);
        if (bleManager.isSupportBle()) {
            if (!bleManager.isBlueEnable()) {
                bleManager.enableBluetooth();
            }
        }
        BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
                .setDeviceMac(MAC)
                .setScanTimeOut(3000)
                .build();
        bleManager.initScanRule(scanRuleConfig);
        bleManager.scan(new BleScanCallback() {
            @Override
            public void onScanStarted(boolean success) {
                Log.i("yjwkhhbj", "onScanStarted");
            }
            @Override
            public void onScanning(BleDevice bleDevice) {
                Log.i("yjwkhhbj", "onScanning mac=" + bleDevice.getMac() + " name=" + bleDevice.getName() + " rssi=" + bleDevice.getRssi());
                bleManager.cancelScan();
                connect(bleDevice);
            }
            @Override
            public void onScanFinished(List<BleDevice> scanResultList) {
                Log.i("yjwkhhbj", "onScanFinished");
                if (scanResultList.isEmpty()) {
                    Log.i("yjwkhhbj", "Not Found Device !");
                }
            }
        });
    }
    private void connect(BleDevice bleDevice) {
        bleManager.connect(bleDevice, new BleGattCallback() {
            @Override
            public void onStartConnect() {
                Log.i("yjwkhhbj", "onStartConnect " + MAC);
            }
            @Override
            public void onConnectFail(BleDevice bleDevice, BleException exception) {
                Log.i("yjwkhhbj", "onConnectFail");
            }
            @Override
            public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
                Log.i("yjwkhhbj", "onConnectSuccess " + status);
                for (BluetoothGattService service : gatt.getServices()) {
                    Log.i("yjwkhhbj", "" + service.getUuid());
                    for (BluetoothGattCharacteristic channel : service.getCharacteristics()) {
                        boolean N = channel.getProperties() == PROPERTY_NOTIFY;
                        boolean I = channel.getProperties() == PROPERTY_INDICATE;
                        boolean R = (channel.getProperties() & PROPERTY_READ) > 0;
                        boolean W = (channel.getProperties() & PROPERTY_WRITE) > 0 && (channel.getProperties() & PROPERTY_WRITE_NO_RESPONSE) > 0;
                        Log.i("yjwkhhbj", "\t" + channel.getUuid() + " WriteType=" + channel.getWriteType() + //" 权限=" + channel.getPermissions() + " 属性=" + channel.getProperties() +
                                " Notify=" + N + " Indicate=" + I + " 可读=" + R + " 可写=" + W);
                    }
                }
                notifyX(bleDevice);
            }
            @Override
            public void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status) {
                Log.i("yjwkhhbj", "onDisConnected");
            }
        });
    }
    private void notifyX(BleDevice bleDevice) {
        bleManager.notify(bleDevice, UUID_S3, UUID_S3_C1, new BleNotifyCallback() {
            @Override
            public void onNotifySuccess() {
                Log.d("yjwkhhbj", "onNotifySuccess");
                write(bleDevice);
            }
            @Override
            public void onNotifyFailure(final BleException exception) {
                Log.i("yjwkhhbj", "onNotifyFailure " + exception.getDescription());
            }
            @Override
            public void onCharacteristicChanged(final byte[] data) {
                Log.d("yjwkhhbj", "onCharacteristicChanged 长度=" + data.length + " Hex=" + HexUtil.formatHexString(data));
            }
        });
    }
    private void write(BleDevice bleDevice) {
        final byte[] OPEN = getData(LOCK, (byte) 0x05);
        final byte[] CLOSE = getData(LOCK, (byte) 0x06);
        final byte[] BATTER = getData(LOCK, (byte) 0x07);
        bleManager.write(bleDevice, UUID_S3, UUID_S3_C2, OPEN, new BleWriteCallback() {
            @Override
            public void onWriteSuccess(int current, int total, byte[] justWrite) {
                Log.d("yjwkhhbj", "onWriteSuccess " + UUID_S3_C2);
            }
            @Override
            public void onWriteFailure(BleException exception) {
                Log.d("yjwkhhbj", "onWriteFailure " + exception.getDescription());
            }
        });
    }
    private byte[] getData(String lock, byte OP) {
        byte[] data = new byte[]{
                (byte) 0xAA, (byte) 0xBB, // 帧头
                (byte) 0x08, OP, (byte) 0x00, // 长度 指令 应答
                (byte) 0xA9, /* 加和：8 + 7 + 0 + 65 + 65 + 21 + 0 + 1 = 169 = 0xA9 */
//              (byte) 0x41, (byte) 0x41, (byte) 0x15, (byte) 0x00, (byte) 0x03, // 设备编号 AA210003
                (byte) lock.charAt(0), (byte) lock.charAt(1), (byte) Integer.parseInt(lock.substring(2, 4)), (byte) 0x00, (byte) Integer.parseInt(lock.substring(6, 8)),
                (byte) 0xCC, (byte) 0xDD // 帧尾
        };
        data[5] = (byte) (data[2] + data[3] + data[4] + data[6] + data[7] + data[8] + data[9] + data[10]);
        return data;
    }
}
